// -----------------------------------------------------------------------------
// Copyright (c) 2014-2023 All rights reserved
// *********************************************************************************
// Project Name : Mul by Booth index4 and Wallace
// Author       : DFY
// File Name    : mul_tc_16_16.v
// Abstract     : 
module mul32(
    input   [31:0]  a,
    input   [31:0]  b,

    output  [63:0]  product
);
//=================================================================================
// Signal and Parameter declaration
//=================================================================================
localparam WORDLEN = 32;  //位数
wire [WORDLEN+1   :0] p_ext      [WORDLEN/2-1:0]; // 32
wire [WORDLEN*2-1 :0] p_shift    [WORDLEN/2-1:0]; // 32 extend to 64
wire [WORDLEN/2-1 :0] switch_out [WORDLEN*2-1:0]; // booth switch (8_32 to 32_8) 把8个32位转化为32个8位以供华莱士树
wire [WORDLEN/2-1 :0] c;  // 14bit 用于华莱士树进位，1bit用于最终加法器进位，1bit用于替代华莱士树进位最低位补0
wire [WORDLEN     :0] src_b = {b[WORDLEN-1:0],1'b0};// 低位补零

wire [WORDLEN/2-3 :0] c_temp [WORDLEN*2-1:0];// 华莱士树级联之间的进位
wire [WORDLEN*2-1 :0] src_Cout;
wire [WORDLEN*2-1 :0] src_Sum;

//=================================================================================
// Body
//=================================================================================

// booth encode求各级部分积，以及加负的进位1
genvar i;
generate
    for (i = 0; i < WORDLEN/2; i=i+1) begin
        booth_encode #(.WORDLEN(WORDLEN)) inst_booth_encode
        (.x(a), .src({src_b[2*i +: 3]}), .p_ext(p_ext[i]), .c(c[i]));  
    end
endgenerate

// 拓展位宽，相当于Booth中的移位
genvar j;
generate
    for (j = 0; j < WORDLEN/2; j=j+1) begin
        assign p_shift[j] = {{(WORDLEN-2-2*j){p_ext[j][WORDLEN+1]}},p_ext[j],{(2*j){c[j]}}};        
    end
endgenerate

//Switch转置 把16个64位转化为64个16位以供华莱士树加
genvar k;
generate
    for (k = 0; k < WORDLEN*2; k=k+1) begin
        assign switch_out[k] = {p_shift[15][k],p_shift[14][k],
                                p_shift[13][k],p_shift[12][k],
                                p_shift[11][k],p_shift[10][k],
                                p_shift[9][k] ,p_shift[8][k],
                                p_shift[7][k] ,p_shift[6][k],
                                p_shift[5][k] ,p_shift[4][k],
                                p_shift[3][k] ,p_shift[2][k],
                                p_shift[1][k] ,p_shift[0][k]};   
    end
endgenerate

//  华莱士树级联
wallace16bit inst0_wallace16bit (.cin(c[WORDLEN/2-3:0]), .in(switch_out[0]), .c(src_Cout[0]), .s(src_Sum[0]), .cout(c_temp[0]));
genvar z;
generate
    for (z = 1; z < WORDLEN*2; z=z+1) begin
        wallace16bit inst_wallace16bit (.cin(c_temp[z-1]), .in(switch_out[z]), .c(src_Cout[z]), .s(src_Sum[z]), .cout(c_temp[z]));
    end
endgenerate

assign product = src_Sum + {src_Cout[WORDLEN*2-2:0],c[WORDLEN/2-2]} + c[WORDLEN/2-1];

endmodule

